home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / FROMUTS / UNIXLIB37B / src / c / mktime < prev    next >
Text File  |  1991-10-08  |  3KB  |  155 lines

  1. static char sccs_id[] = "@(#) mktime.c 3.0 "__DATE__" HJR";
  2.  
  3. /* mktime.c (c) Copyright 1990 H.Rogers */
  4.  
  5. #include <time.h>
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <stdlib.h>
  9.  
  10. static unsigned int __tmonth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
  11.  
  12. static struct tm __tz[1] =    /* time struct */
  13.   {
  14.     { 0,0,0,0,0,0,0,0,-1,0,"" }
  15.   };
  16.  
  17. /* Time zones are "[TZNAME][H][:M][DSTNAME]" where H:M gives the time *west*
  18.  * of GMT for the timezone. If DSTNAME appears then the time zone follows
  19.  * DST rules according to DSTNAME. Examples:
  20.  *
  21.  * "EST5EDT"        USA Eastern time zone
  22.  * "CST6CDT"        USA Central time zone
  23.  * "NFLDT3:30NFLD"    Newfoundland time (1:30 ahead of Eastern)
  24.  * "OZCST-9:30"     Australian Central time zone (no DST)
  25.  *
  26.  * DST is currently unimplemented: Other implementations involve very nasty
  27.  * code in order to cater for exception years (e.g. USA 1972). Also most
  28.  * assume USA rules for DST (which have changed 3 times since 1970), not UK
  29.  * rules (which have changed more often and are more complex :-( ). It's
  30.  * simpler to rely on the SysAdmin changing the system clock twice a year
  31.  * according to local custom. Leap seconds and the century offset are ignored,
  32.  * but the routines are correct to within a second till at least 2038... */
  33.  
  34. int timezone = 0;
  35.  
  36. void tzset(void)
  37. {
  38. char *z;
  39. register int i;
  40.  
  41. if (!(z = getenv("TZ")))
  42.   z = "GMT0UK";     /* default to GMT/UKDST */
  43.  
  44. i = 0; while (isalpha(*z))
  45.   {
  46.   if (i < 3)
  47.     { __tz->tm_zone[i] = *z; i++; }
  48.   z++;
  49.   }
  50. __tz->tm_zone[i] = 0;
  51.  
  52. i = (int)strtol(z,&z,10) * 3600;
  53. if (*z == ':')
  54.   { z++; i += (int)strtol(z,&z,10) * 60; }
  55.  
  56. __tz->tm_gmtoff = timezone = i;
  57. }
  58.  
  59. static struct tm *__mktm(register time_t);
  60.  
  61. struct tm *gmtime(register const time_t *tp)
  62. {
  63. if (!(__tz->tm_zone[0])) tzset();
  64.  
  65. return(__mktm(*tp));
  66. }
  67.  
  68. struct tm *localtime(register const time_t *tp)
  69. {
  70. if (!(__tz->tm_zone[0])) tzset();
  71.  
  72. return(__mktm((*tp) - __tz->tm_gmtoff));
  73. }
  74.  
  75. static struct tm *__mktm(register time_t tm)
  76. {
  77. register struct tm *t = __tz;
  78. register time_t i,j,k;
  79.  
  80. t->tm_isdst = -1;
  81.  
  82. t->tm_wday = (tm / 86400 + 4) % 7;    /* 1st Jan 1970 = Thursday */
  83.  
  84. t->tm_sec = tm % 60; tm /= 60;
  85. t->tm_min = tm % 60; tm /= 60;
  86. t->tm_hour = tm % 24; tm /= 24;
  87.  
  88. i = (365<<1);        /* two years */
  89.  
  90. if (tm >= i)        /* >= 1972 */
  91.   {
  92.   j = (tm - i) / 1461;
  93.   tm -= i + j * 1461;
  94.   k = tm ? ((tm - 1) / 365) : 0;
  95.   if (k)
  96.     {
  97.     tm -= 1 + k * 365;
  98.     __tmonth[1] = 28;
  99.     }
  100.   else
  101.     __tmonth[1] = 29;    /* Feb. hath 29 days in a leap year */
  102.   k += 2 + (j<<2);
  103.   }
  104. else            /* < 1972 */
  105.   {
  106.   k = tm / 365;
  107.   tm -= k * 365;
  108.   __tmonth[1] = 28;
  109.   }
  110.  
  111. t->tm_year = k + 70;
  112. t->tm_yday = tm;
  113.  
  114. k = tm; j = 0; while(k >= (i = __tmonth[j])) k -= i,j++;
  115.  
  116. t->tm_mon = j;
  117. t->tm_mday = k + 1;
  118.  
  119. return(t);
  120. }
  121.  
  122. time_t mktime(register struct tm *t)
  123. {
  124. register time_t r;
  125.  
  126. if ((t->tm_year - 70) < 0) return((time_t)-1);
  127.  
  128. r = t->tm_year - 70;
  129.  
  130. if (r < 2)
  131.   r = r * 365;
  132. else
  133.   {
  134.   register int i,j;
  135.  
  136.   i = (r - 2) & 3;
  137.   j = ((r - 2)>>2) * 1461;
  138.   if (i)
  139.     {
  140.     r = (365<<1) + j + 1 + i * 365;
  141.     }
  142.   else
  143.     r = (365<<1) + j;
  144.   }
  145.  
  146. r += t->tm_yday;
  147. r = r * 24 + t->tm_hour;
  148. r = r * 60 + t->tm_min;
  149. r = r * 60 + t->tm_sec;
  150.  
  151. r += t->tm_gmtoff;    /* mktime() is passed a localtime() struct */
  152.  
  153. return(r);
  154. }
  155.